﻿using System;
using System.Data.SqlClient;
using System.Linq;
using System.Net.Http;
using System.Threading;
using Common.Logging;
using In.Api.Dto.HisWs;
using Newtonsoft.Json;
using OutDbContext;
using Rmq.Center;
using User.Api.BizExtensions;
using User.Api.Helpers;
using User.Api.HttpClients;

namespace Out.TaskRunner.RmqWorkers
{
    public class OrderPickupingChkWorker : IWorker
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof(OrderPickupingChkWorker));

        public void Start(CancellationToken ct)
        {
            if (ct.IsCancellationRequested)
            {
                return;
            }

            using (var consumer = new OrderPickupingChkConsumer())
            {
                consumer.Subscribe((id, count, dt, msg, channel) =>
                {
                    if (msg.OrderType == OrderType.挂号订单)
                    {
                        return ProcessRegOrder(msg.OrderId, channel);
                    }
                    else if (msg.OrderType == OrderType.门诊缴费订单)
                    {
                        return ProcessBillOrder(msg.OrderId, channel);
                    }
                    else if (msg.OrderType == OrderType.住院预缴金订单)
                    {
                        return ProcessInpatientPrepayOrder(msg.OrderId, channel);
                    }

                    return new ConsumedResult { Ack = true };
                });

                while (true)
                {
                    if (ct.IsCancellationRequested)
                    {
                        break;
                    }

                    Thread.Sleep(50);
                }
            }
        }

        private ConsumedResult ProcessRegOrder(int orderId, WrapperChannel channel)
        {
            using (var ctx = new FsssdqfybjyEntities())
            {
                var order = ctx.ApptOrders.FirstOrDefault(x => x.Id == orderId);

                if (order == null)
                {
                    return new ConsumedResult
                    {
                        Ack = true
                    };
                }

                //执行查询挂号状态操作
                var regChkRequest = new Request4GetPillValid();
                regChkRequest.PillNo = order.OrderNo;
                regChkRequest.CardNo = order.CardNo;
                regChkRequest.PillType = "1";

                Response4GetPillValid regChkResponse;
                try
                {
                    var httpClient = InHttpClient.GetClient();
                    var responseMsg = httpClient.PostAsJsonAsync("HisWs/GetPillValid", regChkRequest).Result;
                    responseMsg.EnsureSuccessStatusCode();
                    regChkResponse = responseMsg.Content.ReadAsAsync<Response4GetPillValid>().Result;
                }
                catch (Exception ex)
                {
                    Logger.ErrorFormat("调用院内查询取号状态Api出错,信息：{0}", JsonConvert.SerializeObject(ex));

                    return new ConsumedResult
                    {
                        Ack = false,
                        Delay = 60 * 1000
                    };
                }

                if (regChkResponse.ResultCode == "0")
                {
                    // 取号失败
                    order.OrderStatus = ApptOrderExtensions.OrderStatus.取号失败.ToInt32();
                    ctx.SaveChanges();

                    //if (order.OrderType == ApptOrderExtensions.OrderType.预约.ToInt32().ToString())
                    //{
                    //    // RMQ 取消预约 
                    //    var unapptingProducer = new OrderUnapptingProducer();
                    //    unapptingProducer.Publish(new OrderUnapptingMsg
                    //    {
                    //        OrderType = Rmq.Center.OrderType.挂号订单,
                    //        OrderId = order.Id,
                    //        Reason = 2
                    //    });
                    //}

                    // RMQ 发送用户挂号失败通知
                    var msgProducer = new UserMessageProducer();
                    msgProducer.Publish(new UserMessageMsg
                    {
                        Type = UserMessageType.挂号失败通知,
                        OrderId = order.Id
                    });

                    // RMQ 执行退费操作
                    if (order.SumFee > 0)
                    {
                        var refundingProducer = new OrderRefundingPickupFailedProducer();
                        refundingProducer.Publish(new OrderRefundingPickupFailedMsg
                        {
                            OrderType = OrderType.挂号订单,
                            OrderId = order.Id
                        });
                    }
                }
                else if (regChkResponse.ResultCode == "1")
                {
                    // 取号成功
                    order.OrderStatus = ApptOrderExtensions.OrderStatus.取号成功.ToInt32();
                    order.Remark = regChkResponse.ResultDesc;

                    order.FetchTime = DateTime.Now;
                    ctx.SaveChanges();

                    // RMQ 发送用户挂号成功通知
                    var messageProducer = new UserMessageProducer();
                    messageProducer.Publish(new UserMessageMsg
                    {
                        Type = UserMessageType.挂号成功通知,
                        OrderId = order.Id
                    });

                    // RMQ 发送发货通知
                    if (order.SumFee > 0)
                    {
                        var wxuser = ctx.WxUsers.FirstOrDefault(x => x.Id == order.WxUserId);
                        if (wxuser != null)
                        {
                            WeixinPayV3Helper.DoDeliveryNotify(wxuser.OpenId, order.WxTransactionId,
                               "AP" + order.OrderNo, ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000)
                                                .ToString(), "1", "");
                        }
                    }
                }
            }

            return new ConsumedResult
            {
                Ack = true
            };
        }

        private ConsumedResult ProcessBillOrder(int orderId, WrapperChannel channel)
        {
            using (var ctx = new FsssdqfybjyEntities())
            {
                var order = ctx.ClinRecipeOrders.FirstOrDefault(x => x.Id == orderId);
                if (order == null)
                {
                    return new ConsumedResult
                    {
                        Ack = true
                    };
                }

                var request = new Request4GetPillValid();
                request.PillNo = order.OrderNo;
                request.CardNo = order.CardNo;
                request.PillType = "2";

                Response4GetPillValid response;

                try
                {
                    var httpClient = InHttpClient.GetClient();
                    var responseMsg = httpClient.PostAsJsonAsync("HisWs/GetPillValid", request).Result;
                    responseMsg.EnsureSuccessStatusCode();
                    response = responseMsg.Content.ReadAsAsync<Response4GetPillValid>().Result;
                }
                catch (Exception ex)
                {
                    Logger.ErrorFormat("调用院内查询缴费单状态Api出错,信息：{0}", JsonConvert.SerializeObject(ex));
                    return new ConsumedResult
                    {
                        Ack = false,
                        Delay = 60 * 1000
                    };
                }

                if (response.ResultCode == "0")
                {
                    // 缴费失败
                    order.OrderStatus = BillOrderExtensions.OrderStatus.缴费失败.ToInt32();
                    ctx.SaveChanges();

                    // RMQ 发起缴费失败通知
                    var messageProducer = new UserMessageProducer();
                    messageProducer.Publish(new UserMessageMsg
                    {
                        OrderId = order.Id,
                        Type = UserMessageType.缴费失败通知
                    });

                    // RMQ 发起退款
                    var refundingProducer = new OrderRefundingPickupFailedProducer();
                    refundingProducer.Publish(new OrderRefundingPickupFailedMsg
                    {
                        OrderType = OrderType.门诊缴费订单,
                        OrderId = order.Id
                    });

                    return new ConsumedResult
                    {
                        Ack = true
                    };
                }
                else if (response.ResultCode == "1")
                {
                    // 缴费成功
                    order.OrderStatus = BillOrderExtensions.OrderStatus.缴费成功.ToInt32();
                    order.Remark = response.ResultDesc;
                    order.FetchTime = DateTime.Now;
                    ctx.SaveChanges();

                    // RMQ 发起缴费成功通知
                    var messageProducer = new UserMessageProducer();
                    messageProducer.Publish(new UserMessageMsg
                    {
                        OrderId = order.Id,
                        Type = UserMessageType.缴费成功通知
                    });

                    // RMQ 发送发货通知
                    var wxuser = ctx.WxUsers.FirstOrDefault(x => x.Id == order.WxUserId);
                    if (wxuser != null)
                    {
                        WeixinPayV3Helper.DoDeliveryNotify(wxuser.OpenId, order.WxTransactionId,
                        "BL" + order.OrderNo, ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000)
                                         .ToString(), "1", "");
                    }
                }
            }

            return new ConsumedResult
            {
                Ack = true
            };
        }

        private ConsumedResult ProcessInpatientPrepayOrder(int orderId, WrapperChannel channel)
        {
            using (var ctx = new FsssdqfybjyEntities())
            {
                var order = ctx.InpatientPrepayOrders.FirstOrDefault(x => x.Id == orderId);
                if (order == null)
                {
                    return new ConsumedResult
                    {
                        Ack = true
                    };
                }

                Logger.ErrorFormat("发生缴纳住院预缴金超时问题, OrderId:{0}", order.Id);
            }
            return new ConsumedResult
            {
                Ack = true
            };
        }
    }
}